/**
 * cluelog服务实现
 *
 * @author sxf
 * @email sxf02615@163.com
 * @date 2025/1/15
 */
package com.sxf.crm.service.impl;


import com.sxf.crm.dto.ClueLogDTO;
import com.sxf.crm.entity.ClueLog;
import com.sxf.crm.entity.Clue;
import com.sxf.crm.entity.User;
import com.sxf.crm.enums.ClueLogOperationType;
import com.sxf.crm.repository.ClueLogRepository;
import com.sxf.crm.service.ClueLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional
public class ClueLogServiceImpl implements ClueLogService {
    
    private final ClueLogRepository clueLogRepository;
    
    @Override
    public ClueLog logCreate(Clue clue, User operator) {
        ClueLog log = new ClueLog();
        log.setClue(clue);
        log.setOperator(operator);
        log.setOperationType(ClueLogOperationType.CREATE);
        log.setOperationTime(System.currentTimeMillis());
        log.setOperationDesc("创建线索");
        log.setStatusAfter(clue.getStatus().getLabel());
        return clueLogRepository.save(log);
    }
    
    @Override
    public ClueLog logUpdate(Clue clue, User operator, String details) {
        ClueLog log = new ClueLog();
        log.setClue(clue);
        log.setOperator(operator);
        log.setOperationType(ClueLogOperationType.UPDATE);
        log.setOperationTime(System.currentTimeMillis());
        log.setOperationDesc("更新线索信息");
        log.setDetails(details);
        return clueLogRepository.save(log);
    }
    
    @Override
    public ClueLog logStatusChange(Clue clue, User operator, String statusBefore, String statusAfter) {
        ClueLog log = new ClueLog();
        log.setClue(clue);
        log.setOperator(operator);
        log.setOperationType(ClueLogOperationType.STATUS_CHANGE);
        log.setOperationTime(System.currentTimeMillis());
        log.setOperationDesc("修改状态");
        log.setStatusBefore(statusBefore);
        log.setStatusAfter(statusAfter);
        return clueLogRepository.save(log);
    }
    
    @Override
    public ClueLog logAssign(Clue clue, User operator, User owner) {
        ClueLog log = new ClueLog();
        log.setClue(clue);
        log.setOperator(operator);
        log.setOperationType(ClueLogOperationType.ASSIGN);
        log.setOperationTime(System.currentTimeMillis());
        log.setOperationDesc("分配给" + owner.getUsername());
        log.setStatusBefore(clue.getStatus().getLabel());
        log.setStatusAfter("ASSIGNED");
        return clueLogRepository.save(log);
    }
    
    @Override
    public ClueLog logClaim(Clue clue, User operator) {
        ClueLog log = new ClueLog();
        log.setClue(clue);
        log.setOperator(operator);
        log.setOperationType(ClueLogOperationType.CLAIM);
        log.setOperationTime(System.currentTimeMillis());
        log.setOperationDesc("领取线索");
        log.setStatusBefore(clue.getStatus().getLabel());
        log.setStatusAfter("CLAIMED");
        return clueLogRepository.save(log);
    }
    
    @Override
    public ClueLog logRecycle(Clue clue, User operator) {
        ClueLog log = new ClueLog();
        log.setClue(clue);
        log.setOperator(operator);
        log.setOperationType(ClueLogOperationType.RECYCLE);
        log.setOperationTime(System.currentTimeMillis());
        log.setOperationDesc("回收线索");
        log.setStatusBefore(clue.getStatus().getLabel());
        log.setStatusAfter("RECYCLED");
        return clueLogRepository.save(log);
    }
    
    @Override
    public ClueLog logFollowUp(Clue clue, User operator, String details) {
        ClueLog log = new ClueLog();
        log.setClue(clue);
        log.setOperator(operator);
        log.setOperationType(ClueLogOperationType.FOLLOW_UP);
        log.setOperationTime(System.currentTimeMillis());
        log.setOperationDesc("跟进记录");
        log.setDetails(details);
        return clueLogRepository.save(log);
    }
    
    @Override
    public ClueLog logConvert(Clue clue, User operator, String convertType, String details) {
        ClueLog log = new ClueLog();
        log.setClue(clue);
        log.setOperator(operator);
        log.setOperationType(ClueLogOperationType.CONVERT);
        log.setOperationTime(System.currentTimeMillis());
        log.setOperationDesc("转化为" + convertType);
        log.setStatusBefore(clue.getStatus().getLabel());
        log.setStatusAfter("CONVERTED");
        log.setDetails(details);
        return clueLogRepository.save(log);
    }
    
    @Override
    public List<ClueLogDTO> getLogsByClueId(Long clueId) {
        return clueLogRepository.findByClueIdOrderByOperationTimeDesc(clueId)
                .stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<ClueLogDTO> getLogsByOperator(Long operatorId) {
        return clueLogRepository.findByOperatorId(operatorId)
                .stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    private ClueLogDTO convertToDTO(ClueLog log) {
        ClueLogDTO dto = new ClueLogDTO();
        BeanUtils.copyProperties(log, dto);
        dto.setClueId(log.getClue().getId());
        dto.setOperatorId(log.getOperator().getId());
        dto.setOperatorName(log.getOperator().getUsername());
        dto.setOperationTypeLabel(log.getOperationType().getLabel());
        dto.setStatusBefore(log.getStatusBefore());
        dto.setStatusAfter(log.getStatusAfter());
        return dto;
    }

    @Override
    public void logAccept(Clue clue, User operator) {
        ClueLog log = new ClueLog();
        log.setClue(clue);
        log.setOperator(operator);
        log.setOperationType(ClueLogOperationType.ACCEPT);
        log.setOperationTime(System.currentTimeMillis());
        log.setOperationDesc("接受线索");
        log.setStatusBefore(clue.getStatus().getLabel());
        log.setStatusAfter("ACCEPTED");
        clueLogRepository.save(log);
    }
}